﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;

namespace InvasionWars
{
    public partial class ServerConnection : Form
    {
        
        private Server server;
        private const int defaultPort = 8500;
        
        public ClientServerConn JoinedGame;

        public ServerConnection()
        {
            InitializeComponent();
            resetConnection();
        }

        private void resetConnection()
        {
            btnJoin.Enabled = false;
            btnRefresh.Enabled = false;
            btnCreate.Enabled = false;
            lBxActiveSessions.ClearSelected();
            lBxActiveSessions.Items.Clear();

        }
        private void updateFormConnected()
        {
            //lBxActiveSessions.SelectedIndex = 0;
            btnRefresh.Enabled = true;
            btnJoin.Enabled = true;
            btnCreate.Enabled = true;
            txtServerName.Enabled = false;
            btnConnect.Enabled = false;
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            //connect to the server on default port
            server = new Server();

            try
            {
                try
                {
                    server.ServerIP = IPAddress.Parse(txtServerName.Text);
                }
                catch(FormatException fe)
                {
                    txtStatus.Text = "ServerName text is not an IP address";
                }
                server.ServerName = txtServerName.Text;
                server.Port = Convert.ToInt16(txtServerPort.Text);
                int result = server.Connect();

                if (result == 0)
                {
                    txtStatus.ForeColor = Color.Green;
                    txtStatus.Text = "Connection with Server " + server.ServerName + "established!";
                    txtServerPort.Text = "" + server.Port;
                    //server.Refresh();
                    refresh();
                    updateFormConnected();
                    server.connState = ServerConnectionState.CONNECTED;

                    
                }
                else if (result == 1)
                {
                    txtStatus.ForeColor = Color.Blue;
                    txtStatus.Text = "Offline Testing Connection Estabished";
                    refresh();
                    updateFormConnected();
                    server.connState = ServerConnectionState.CONNECTED;
                }
                else
                {
                    txtStatus.ForeColor = Color.Red;
                    txtStatus.Text = "Connection failed";
                    server.connState = ServerConnectionState.NOT_CONNECTED;
                }

                updateFormConnected();
            }
            catch (FormatException fe)
            {
                //notify that it is not a valid INT
                txtStatus.ForeColor = Color.Red;
                string msg = "Port is not a valid integer Number";
                err.SetError(txtServerPort, msg);
                txtStatus.Text = msg;

            }
            catch (OverflowException ofe)
            {
                //port number is too long.
                txtStatus.ForeColor = Color.Red;
                string msg = "Port number is too long";
                err.SetError(txtServerPort, msg);
                txtStatus.Text = msg;
            }
            catch (Exception any)
            {
                txtStatus.ForeColor = Color.Red;
                string msg = any.Message;
                err.SetError(txtServerPort, msg);
                txtStatus.Text = msg;
            }
        }

        private void btnJoin_Click(object sender, EventArgs e)
        {
            
            if (lBxActiveSessions.SelectedIndex >= 0)
            {
                if (!((GameSession)lBxActiveSessions.SelectedItem).IsFull)
                {
                    //join selected match


                    int result = server.Join(((GameSession)lBxActiveSessions.SelectedItem).GameID);
                    if (result  == 0)
                    {
                        JoinedGame = new ClientServerConn(server.ServerName, server.Port);
                        txtStatus.ForeColor = Color.Green;
                        txtStatus.Text = "Joining Game on port " + ((GameSession)lBxActiveSessions.SelectedItem).GameID;
                        this.DialogResult = DialogResult.OK;
                    }
                    else
                    {
                        //err joining game
                        txtStatus.ForeColor = Color.Red;
                        txtStatus.Text = "Error Joining Game:  Refresh and try again;";

                    }
                }
                else
                {
                    txtStatus.ForeColor = Color.Red;
                    txtStatus.Text = "Game is Full";

                }
                
                
                
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            //reload data from the server
            refresh();
            
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }



        private void refresh()
        {
            if (server.connState == ServerConnectionState.CONNECTED)
            {
                try
                {
                    List<GameSession> activeSessions = server.Refresh();
                    lBxActiveSessions.Items.Clear();
                    if (activeSessions.Count > 0)
                    {
                        foreach (GameSession session in activeSessions)
                        {
                            lBxActiveSessions.Items.Add(session);
                        }
                    }
                        txtStatus.ForeColor = Color.Green;
                        txtStatus.Text = "Refresh Successful";
                    
                }
                catch (Exception any)
                {
                    txtStatus.ForeColor = Color.Red;
                    txtStatus.Text = "Refresh Error: " + any.Message;
                }
            }

        }

        private void ServerConnection_FormClosing(object sender, FormClosingEventArgs e)
        {
            //if connected notify the server we are disconnecting
            if (server == null || server.connState == ServerConnectionState.NOT_CONNECTED)
            {
                
                DialogResult = DialogResult.Cancel;
            }

            
        }



        private void btnCreate_Click(object sender, EventArgs e)
        {
            string matchName;
            NewMatch newMatchDiag = new NewMatch();
            newMatchDiag.ShowDialog();
            if (newMatchDiag.DialogResult == DialogResult.OK)
            {
                matchName = newMatchDiag.MatchName;
                server.CreateMatch(matchName, server.Port - defaultPort);
                gBxCreatedMatch.Visible = true;
                txtMatchID.Text = "" + (server.Port - defaultPort);
                txtMatchName.Text = matchName;
                btnCreate.Enabled = false;
                //refresh();
                

                lBxActiveSessions.Enabled = false;
                btnJoin.Enabled = false;
                btnRefresh.Enabled = false;
                
                txtStatus.ForeColor = Color.Green;
                txtStatus.Text = "Creating Game on port " + server.Port;
                waitTimer.Enabled = true;
            }

            
        }

        private void waitTimer_Tick(object sender, EventArgs e)
        {
            if (server.State == GameState.PLAYING)
            {
                JoinedGame = new ClientServerConn(server.ServerName, server.Port);
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            else
            {
                txtStatus.Text = DateTime.Now + ":  Still waiting for other client.";
            }
        }




    }
}
